package streamflow.engine.topology.storm;
import backtype.storm.LocalDRPC;
import backtype.storm.drpc.DRPCSpout;
import backtype.storm.generated.StormTopology;
import backtype.storm.topology.BoltDeclarer;
import backtype.storm.topology.SpoutDeclarer;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields;
import java.util.Map;
import streamflow.engine.framework.FrameworkException;
import streamflow.engine.topology.TopologyCreator;
import streamflow.engine.wrapper.storm.BasicBoltWrapper;
import streamflow.engine.wrapper.storm.RichBoltWrapper;
import streamflow.engine.wrapper.storm.RichSpoutWrapper;
import streamflow.model.Cluster;
import streamflow.model.Component;
import streamflow.model.Topology;
import streamflow.model.TopologyComponent;
import streamflow.model.TopologyConnector;
import streamflow.model.config.StreamflowConfig;
import org.apache.commons.lang.StringUtils;
public class StandardTopologyCreator implements TopologyCreator {
public static final String TYPE = "STANDARD";
@Override
public StormTopology build(Topology topology, StreamflowConfig configuration, boolean isClusterMode)
throws FrameworkException {
TopologyBuilder builder = new TopologyBuilder();
// Iterate over all of the nodes to add them to the topology
for (TopologyComponent component : topology.getDeployedConfig().getComponents().values()) {
if (component.getType().equalsIgnoreCase(Component.STORM_SPOUT_TYPE)) {
SpoutDeclarer spoutDeclarer;
// Handle the special case for the DRPC Spout which requires
// potential startup of a local DRPC server
if (component.getMainClass().equals(DRPCSpout.class.getName())) {
// Attempt to get the name of the DRPC function
String drpcFunction = component.getProperties().get("drpc-function");
if (StringUtils.isBlank(drpcFunction)) {
drpcFunction = topology.getId();
}
if (configuration.getSelectedCluster().getId().equals(Cluster.LOCAL)) {
// Local cluster deploys require manual startup of a DRPC server
LocalDRPC drpcServer = new LocalDRPC();
// Create the DRPC spout specifying the name of the DRPC function
DRPCSpout drpcSpout = new DRPCSpout(drpcFunction, drpcServer);
spoutDeclarer = builder.setSpout(
component.getKey(), drpcSpout, component.getParallelism());
} else {
// Create the DRPC spout using the DRPC server on the cluster
DRPCSpout drpcSpout = new DRPCSpout(drpcFunction);
spoutDeclarer = builder.setSpout(
component.getKey(), drpcSpout, component.getParallelism());
}
} else {
RichSpoutWrapper richSpoutWrapper = new RichSpoutWrapper(
topology, component, isClusterMode, configuration);
// Add the spout instance to the topology
spoutDeclarer = builder.setSpout(
component.getKey(), richSpoutWrapper, component.getParallelism());
}
// Add the properties for the specific component as component specific properties
for (Map.Entry<String, String> componentProperty
: component.getProperties().entrySet()) {
spoutDeclarer.addConfiguration(
componentProperty.getKey(), componentProperty.getValue());
}
} else if (component.getType().equalsIgnoreCase(Component.STORM_BOLT_TYPE)) {
BoltDeclarer boltDeclarer;
try {
// Attempt to load the bolt as a RichBolt
RichBoltWrapper richBoltWrapper = new RichBoltWrapper(
topology, component, isClusterMode, configuration);
// Add the spout instance to the topology
boltDeclarer = builder.setBolt(
component.getKey(), richBoltWrapper, component.getParallelism());
} catch (FrameworkException ex) {
// Attempt to load the bolt as a BasicBolt
BasicBoltWrapper basicBoltWrapper = new BasicBoltWrapper(
topology, component, isClusterMode, configuration);
// Add the spout instance to the topology
boltDeclarer = builder.setBolt(
component.getKey(), basicBoltWrapper, component.getParallelism());
}
// Add the properties for the specific component as component specific properties
for (Map.Entry<String, String> componentProperty : component.getProperties().entrySet()) {
boltDeclarer.addConfiguration(
componentProperty.getKey(), componentProperty.getValue());
}
// Iterate over each of the edges to see if it is the target
for (TopologyConnector connector : topology.getDeployedConfig().getConnectors().values()) {
// The current edge is the target for the edge
if (connector.getTargetComponentKey().equals(component.getKey())) {
String grouping = connector.getGrouping();
if (grouping.equalsIgnoreCase("Shuffle")) {
boltDeclarer.shuffleGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface());
} else if (grouping.equalsIgnoreCase("Fields")) {
boltDeclarer.fieldsGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface(),
new Fields(connector.getGroupingRef()));
} else if (grouping.equalsIgnoreCase("All")) {
boltDeclarer.allGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface());
} else if (grouping.equalsIgnoreCase("Global")) {
boltDeclarer.globalGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface());
} else if (grouping.equalsIgnoreCase("None")) {
boltDeclarer.noneGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface());
} else if (grouping.equalsIgnoreCase("Direct")) {
boltDeclarer.directGrouping(
connector.getSourceComponentKey(),
connector.getSourceComponentInterface());
}
}
}
}
}
// Build the topology using the topology configured in the builder
return builder.createTopology();
}
}